﻿using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Sustainalytics.Entities
{
    public class Account : IEntity
    {
        public Guid Id { get; set; }

        public Guid CurrentEsgProfile { get; set; }
        public Guid? UpcomingEsgProfile { get; set; }

        public string Name { get; set; }

        [BsonRepresentation(BsonType.String)]
        public RelationshipType RelationshipType { get; set; }

        public string Office { get; set; }

        public AccountManager AccountManager { get; set; }

        public DateTime ModifiedOn { get; set; }

        [BsonRepresentation(BsonType.String)]
        public Status Status { get; set; }

        public DateTime LastCrmSync { get; set; }

        public bool HasPlatformAccess { get; set; }

        [BsonRepresentation(BsonType.String)]
        public AccessLevel PlatformTier { get; set; }
    }

    public class AccountIpAuthentication : IEntity
    {
        public Guid Id { get; set; } //AccountId

        public string AccountName { get; set; }

        public Guid UserId { get; set; }
        public string UserName { get; set; }

        [BsonRepresentation(BsonType.String)]
        public Status Status { get; set; }

        public List<IpData> IpDatas { get; set; }

        public override string ToString()
        {
            return string.Format("Id: {0}, UserName: {1},  IpDatas: {2}", Id, UserName, IpDatas);
        }

        public static bool IsNullOrEmpty(AccountIpAuthentication auth)
        {
            if (auth == null)
                return true;

            var cond = auth.Id == default(Guid) && auth.Status == default(Status) && auth.UserId == default(Guid) && string.IsNullOrEmpty(auth.UserName);
            var condIpData = IsEmptyIpData(auth);
            return cond && condIpData;
        }

        public static bool IsEmptyIpData(AccountIpAuthentication auth)
        {
            var condIpData = auth.IpDatas == null ||
                             (auth.IpDatas != null &&
                              (!auth.IpDatas.Any() ||
                               (auth.IpDatas.Any() && auth.IpDatas.All(c => string.IsNullOrEmpty(c.IpFrom)))));
            return condIpData;
        }

        public static Dictionary<string, string> ValidateData(AccountIpAuthentication auth)
        {
            if (IsNullOrEmpty(auth))
                return new Dictionary<string, string> { { "AccountIpAuthentication", "The object is null or empty" } };

            var dict = new Dictionary<string, string>();

            if (auth.Id == Guid.Empty)
                dict.Add("Id", "The guid for the account id is empty");

            if (IsEmptyIpData(auth))
                dict.Add("IpDatas", "The data for ip is empty");

            if (auth.UserId == default(Guid))
                dict.Add("UserId", "The user id guid is a default one");

            if (string.IsNullOrEmpty(auth.UserName))
                dict.Add("UserName", "The user name sent is empty");

            return dict;
        }
    }

    public class IpData
    {
        public IpData(string ipFrom, string ipTo)
        {
            IpFrom = ipFrom;
            IpTo = ipTo;
        }

        public string IpFrom { get; private set; }
        public string IpTo { get; private set; } //if it is null or empty than it is not an ip range definition

        public override string ToString()
        {
            return string.Format("IpFrom: {0}, IpTo: {1}", IpFrom, IpTo);
        }
    }
}
